package com.thiswhyme.seata.order.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.rm.datasource.xa.DataSourceProxyXA;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

/**
 * @description:
 * @author: thiswhyme
 * @date: 2021/3/16
 */
@Slf4j
//@Configuration
public class DataSourceConfig {

    @Value("${seata.transactional-type:DEFAULT}")
    private String transactionalType;

    @Primary
    @Bean(name = "primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid")
    public DataSource dataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "xaDataSourceProxy")
    public DataSourceProxyXA xaDataSourceProxy(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceProxyXA(dataSource);
    }

    @Bean(name = "atDataSourceProxy")
    public DataSourceProxy atDataSourceProxy(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceProxy(dataSource);
    }

    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource(@Qualifier("primaryDataSource") DataSource primaryDataSource,
                                                          @Qualifier("atDataSourceProxy") DataSource atDataSourceProxy,
                                                          @Qualifier("xaDataSourceProxy") DataSource xaDataSourceProxy) {
        if(DataSourceKey.AT.name().equals(transactionalType)) {
            log.info("启用数据源：AT");
            return atDataSourceProxy;
        } else if(DataSourceKey.XA.name().equals(transactionalType)) {
            log.info("启用数据源：XA");
            return xaDataSourceProxy;
        } else {
            log.info("启用数据源：DEFAULT");
            return primaryDataSource;
        }
    }

    @Bean(name = "sqlSessionFactory")
    public MybatisSqlSessionFactoryBean sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource) {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        return sqlSessionFactory;
    }

    @Bean(name = "sqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(
            @Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean
    public PlatformTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
